#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "lex.h"
#include "parser.h"

char *name[] = {
	"FUNCTION", "ENDFUNCTION", "MAIN", "VAR", "ADD", "MULT", "LABEL", 
	"AND", "OR", "NOT",	"MOVE", "IFZERO", "IFTRUE", "IFFALSE", "IFGREATER",
	"IFLESS", "IFEQUAL", "GOTO", "CALL", "READ", "WRITE", "RETURN", "IFNZERO",
	"SKIP", "RESTORE", "SETPARAM", "TRUE", "FALSE", "REF", "VAL", "RES",
	"VALRES", "PARAM", "ERROR_TOKEN", "STRING", "NAME", "INTEGER", "NUMBER",
	"BOOLEAN", "DIGIT", "true", "false"
};

YYSTYPE yylval;

int errors = 0;

/* Mostra erros */
void error(char *fmt, ...) {
	va_list args;

	errors++;
	fprintf(stderr, "Linha %d: ", lineno);
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	printf("\n");
}

/* mostra quantos erros foram encontrados */
void error_count() {
	if (errors > 1)
		printf("Foram encontrados %d erros.\n", errors);
	else if (errors == 1)
		printf("Foi encontrado %d erro.\n", errors);
	else
		printf("Nao foi encontrado nenhum erro.\n");
}

/* funcao do parser para tratar erros */
void yyerror(char *msg) {
	error(msg);
}

/* funcao chamada pelo lexer quando chega no final da linha;
 * podemos resetar yyin (o arq de entrada) e retornar 0
 * se queremos processar outro arquivo, senao retorna 1
 */
extern int yywrap(void) {
	return 1;
}

int main(int argc, char **argv) {
	int token;

	yyin = NULL;
	if (argc == 2)
		yyin = fopen(argv[1], "r");
	if (yyin == NULL)
		yyin = stdin;

	#ifdef DEBUG_LEX 
	// mostra todos os tokens
	while ((token = yylex()) != 0) {
		printf("Token: %d %s ", token, name[token - FUNCTION]);
		switch(token) {
		case NUMBER:
			printf("%d\n", yylval.integer);
			break;
		case NAME:
			printf("%s\n", yylval.str);
			free(yylval.str);
			break;
		default:
			printf("\n");
			break;
		}
	} 
	#endif

	yyparse();
	error_count();
	return errors ? 1 : 0;
	return 0;
}
